package com.itheima.dbservice;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.itheima.pojo.User;
import com.itheima.bean.CodeBean;
import com.itheima.exception.CommonException;
import com.itheima.pojo.UserInfo;
import com.itheima.template.FaceCheckTemplate;
import com.itheima.template.HuanXinTemplate;
import com.itheima.util.MqUtil;
import com.itheima.utils.JwtUtils;
import com.itheima.template.OssTemplate;
import com.itheima.template.SmsTemplate;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class SsoService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private SmsTemplate smsTemplate;
    @DubboReference(timeout = 1000)
    private UserService userService;
    @Autowired
    private OssTemplate ossTemplate;
    @Autowired
    private FaceCheckTemplate faceCheckTemplate;
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private HuanXinTemplate huanXinTemplate;
    @Autowired
    private AmqpTemplate amqpTemplate;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    public void sendCode(Map<String, String> phoneMap) {
        String phone = phoneMap.get("phone");
        String redisCode = CodeBean.CODE + phone;
        if(ObjectUtil.isNotNull(redisTemplate.opsForValue().get(redisCode))){
//            throw new CommonException("验证码并未失效");
        }

        String ran = Convert.toStr(RandomUtil.randomInt(100000, 999999));
        redisTemplate.opsForValue().set(redisCode, ran, 3, TimeUnit.MINUTES);
        //发送短信
//        smsTemplate.sendSms(phone, ran);
    }

    public Map loginVerification(Map<String, String> loginMap) {
        String phone = loginMap.get("phone");
        String redisCode = CodeBean.CODE + phone;

        String code = Convert.toStr(redisTemplate.opsForValue().get(redisCode));

        if (StrUtil.isBlank(code)){
            throw new CommonException("验证码无效");
        }

        //假数据测试
        code = "666666";
        String verificationCode = loginMap.get("verificationCode");
        if (!StrUtil.equals(verificationCode, code)){
            throw new CommonException("验证码有误");
        }

        //准备日志数据type
        boolean flag = false;
        User user = userService.getByPhone(phone);
        //表示登录
        String type = "01";
        if (ObjectUtil.isNull(user)){
            //表示注册
            type = "0102";
            //新用户
            flag = true;
            user = new User();
            user.setMobile(phone);
            user.setPassword(DigestUtil.md5Hex("123456"));
            user.setCreated(new Date());
            user.setUpdated(new Date());
            Long id = userService.save(user);
            user.setId(id);

            //环信用户注册
            Boolean res = huanXinTemplate.createUser(CodeBean.HX_USER_PREFIX + id, "123456");
            if (!res){
                //再次注册
                huanXinTemplate.createUser(CodeBean.HX_USER_PREFIX + id, "123456");
//                throw new CommonException("环信注册失败");
            }
            user.setHxUser(CodeBean.HX_USER_PREFIX + id);
            user.setHxPassword("123456");
            userService.updateInfo(user);
        }
        //检查用户被冻结范围
        log.info(CodeBean.FREEZE_USER + user.getId());
        String map1 = Convert.toStr(stringRedisTemplate.opsForValue().get(CodeBean.FREEZE_USER + user.getId()));
        Map freezeMap = JSONUtil.toBean(map1, Map.class);
        //检查是否有该用户
        if (freezeMap.size() != 0){
            //检查用户被冻结范围，1为冻结登录，2为冻结发言，3为冻结发布动态
            Integer freezingRange = Convert.toInt(freezeMap.get("freezingRange"));
            if (ObjectUtil.equal(1, freezingRange)){
                throw new CommonException("您的账户已被冻结");
            }
        }

        //发送消息
//        MqUtil mqUtil = new MqUtil();
//        mqUtil.sendMessage(user, type);

        //构造Map集合
        Map<String, Object> msg = new HashMap<>();
        msg.put("userId", user.getId());
        msg.put("date", new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
        msg.put("type", type);
        String message = JSON.toJSONString(msg);
        //发送消息
        try {
            amqpTemplate.convertSendAndReceive("tanhua.log.exchange",
                    "log.user",message);
        }catch (Exception e) {
            e.printStackTrace();
        }

        //存放用户id
        String token = JwtUtils.getToken(user.getId());
        log.info(token);

        Map map = new HashMap();
        map.put("token", token);
        map.put("isNew", flag);

        redisTemplate.delete(redisCode);

        return map;
    }


    public void loginReginfoHead(String token, MultipartFile headPhoto) {
        Claims claimsBody = JwtUtils.getClaimsBody(token);
        int i = JwtUtils.verifyToken(claimsBody);
        if (i == 1 || i == 2) {
            throw new CommonException("用户登录信息已过期");
        }

        Long id = Convert.toLong(claimsBody.get("id"));
        log.info("id为" + id);

        int status;
        String imageUrl = null;
        try {
            imageUrl = ossTemplate.upload(headPhoto.getOriginalFilename(), headPhoto.getInputStream());
            status = faceCheckTemplate.faceCheck(imageUrl);
        } catch (IOException e) {
            e.printStackTrace();
            throw new CommonException("头像上传失败！");
        }
        if (status != 0){
            throw new CommonException("上传的非人像");
        }
        //保存头像地址
        UserInfo userInfo = new UserInfo();
        userInfo.setId(id);
        userInfo.setAvatar(imageUrl);
        userInfoService.updateImage(userInfo);
    }
}
